//
//  UIGridView.m
//  X-Touch2
//
//  Created by shengchao yang on 12-3-25.
//  Copyright (c) 2012年 foxhis. All rights reserved.
//

#import "UIGridView.h"
#import "FileManager.h"
#import "Singleton.h"

@interface UIGridView (Private)
-(void) loadScrollViewWithPage:(int)page;
-(void) loadData;
-(void) removeOthersItems:(NSInteger) pageIndex;
@end

@implementation UIGridView
@synthesize dataSource;
@synthesize delegate;

-(id)initWithTarget:(id)target withFrame:(CGRect)frame withTag:(NSInteger)tag {
    self = [super initWithFrame:frame];
    if (self) {
        loadPageCount = 1;
        self.tag = tag;
        _targert = target;
        _frame = frame;
        self.delegate = _targert;
        self.dataSource = _targert;
        _currentPageIndex = 0;
        
        _gridViewItems = [[NSMutableArray alloc] init];
        _scrollView = [[UIScrollView alloc] init];
        _pageControl = [[UIPageControl alloc] init];
        _resuedGridItems = [[NSMutableSet alloc] init];
        
        //回调函数获取参数
        _rows = [self.dataSource gridViewRows:self];
        _cols = [self.dataSource gridViewCols:self];
        _totalCount = [self.dataSource gridViewTotalCount:self];
        _pages = (_totalCount%(_rows*_cols)==0?0:1) + _totalCount/(_rows*_cols);//计算总页数
        
        //几个开关设置
        if ([_targert respondsToSelector:@selector(gridViewPageControlEnable:)]) {
            _pageControlEnable = [self.dataSource gridViewPageControlEnable:self];
        }else{
            _pageControlEnable = YES;//是否使用pageControl控件
        }
        if ([_targert respondsToSelector:@selector(gridViewDirection:)]) {
            _direction = [self.dataSource gridViewDirection:self];
        }else{
            _direction = YES;//滑动的方向(YES-横向默认  NO-纵向)
        }
        if ([_targert respondsToSelector:@selector(gridViewShowScrollIndicator:)]) {
            _showScrollIndicator = [self.dataSource gridViewShowScrollIndicator:self];
        }else{
            _showScrollIndicator = NO;//是否显示滑动条Indicator(默认NO)
        }
        
        //控件的大小位置        
        if ([_targert respondsToSelector:@selector(gridViewItemStartPoint:)]) {
            _itemStartPoint = [self.dataSource gridViewItemStartPoint:self];
        }else{
            _itemStartPoint = CGPointMake(10,10);//默认(10,10) 
        }
        if ([_targert respondsToSelector:@selector(gridViewItemMargin:)]) {
            _itemMargin = [self.dataSource gridViewItemMargin:self];
        }else{
            _itemMargin = CGSizeMake(10,10);//默认(10,10)
        }
        if ([_targert respondsToSelector:@selector(gridViewControlFrame:)]) {
            _controlFrame = [self.dataSource gridViewControlFrame:self];
        }else{
            _controlFrame = CGRectMake(0,_frame.size.height-30,_frame.size.width,30);
        }
        if ([_targert respondsToSelector:@selector(gridViewScrollFrame:)]) {
            _scrollFrame = [self.dataSource gridViewScrollFrame:self];
        }else{
            if (_pageControlEnable) {
                _scrollFrame = CGRectMake(0,0,_frame.size.width,_frame.size.height-_controlFrame.size.height);
            }else{
                _scrollFrame = CGRectMake(0,0,_frame.size.width,_frame.size.height);
            }
        }
        if ([_targert respondsToSelector:@selector(gridViewItemSize:)]) {//自动计算item的大小,通常不用重载
            _itemSize = [self.dataSource gridViewItemSize:self];
        }else{
            _itemSize = CGSizeMake((int)((_scrollFrame.size.width -2*_itemStartPoint.x-(_cols-1)*_itemMargin.width)  /_cols), 
                                   (int)((_scrollFrame.size.height-2*_itemStartPoint.y-(_rows-1)*_itemMargin.height))/_rows);
        }      
        
        _scrollView.frame = _scrollFrame;
        _scrollView.pagingEnabled = YES;
        _scrollView.scrollsToTop = NO;
        _scrollView.delegate = self;
        
        if (!_showScrollIndicator) {//不显示滚动条
            _scrollView.showsHorizontalScrollIndicator = NO;
            _scrollView.showsVerticalScrollIndicator = NO;
        }
        [self addSubview:_scrollView];
        
        _pageControl.frame = _controlFrame;
        _pageControl.currentPage = 0;
        if (_pageControlEnable) {
            [_pageControl addTarget:self action:@selector(loadData) forControlEvents:UIControlEventValueChanged];
            [self addSubview:_pageControl];
        }
        
        [self reloadData];
    }
    return self;
}
-(void)setCurrentPageIndex:(NSInteger)index{
    _currentPageIndex = index;
}
//重新加载可见的item
-(void) reloadData{
    _totalCount = [self.dataSource gridViewTotalCount:self];
    _pages = (_totalCount%(_rows*_cols)==0?0:1) + _totalCount/(_rows*_cols);//计算总页数
    if (_direction) {//横向
        _scrollView.contentSize = CGSizeMake(_scrollFrame.size.width * _pages, _scrollFrame.size.height);//注意是改变内容范围大小
        if (_showScrollIndicator) {
            _scrollView.showsHorizontalScrollIndicator = YES;
            _scrollView.showsVerticalScrollIndicator = NO;
        }
    }else{  
        _scrollView.contentSize = CGSizeMake(_scrollFrame.size.width, _scrollFrame.size.height * _pages);//注意是改变内容范围大小
        if (_showScrollIndicator) {
            _scrollView.showsHorizontalScrollIndicator = NO;
            _scrollView.showsVerticalScrollIndicator = YES;
        }
    }
    
    //移除已经实例化的对象
    for (UIView *view in _scrollView.subviews) {
        if ([view isKindOfClass:[GridViewItem class]]) {
            [_resuedGridItems addObject:view];//回收利用
            [view removeFromSuperview];
        }
    }
    _pageControl.numberOfPages = _pages;
    _pageControl.currentPage = _currentPageIndex < _pages ? _currentPageIndex : 0;
    [self loadData];
}
//将所有不可见的item移除并释放内存
-(void) removeOthersItems:(NSInteger) pageIndex{
    for (UIView *view in _scrollView.subviews) {
        if ([view isKindOfClass:[GridViewItem class]]) {
            NSInteger index = view.tag - TagOfUIGridViewItem;
            if (index < (pageIndex-loadPageCount)*_rows*_cols || index >= (pageIndex + (loadPageCount+1))*_rows*_cols) {
                GridViewItem *item = (GridViewItem *)view;
                [_resuedGridItems addObject:item];//回收利用
                [item removeFromSuperview];
            }
        }
    }
}
//获取可以重用的item对象
-(GridViewItem *)dequeueReusableCellWithIdentifier:(NSString *)identifier{
	GridViewItem * cell = [[_resuedGridItems anyObject] retain];
	if (cell == nil){
		return nil; 
    }
	[_resuedGridItems removeObject: cell];
	return cell;
}
#pragma mark - pageControl delegate
//pageControl的委托方法
-(void)loadData{  
    _scrollView.scrollEnabled = YES;
    int pageIndex = _pageControl.currentPage;
    _currentPageIndex = pageIndex;
    if (_direction) {
        CGRect frame = CGRectMake(pageIndex*_scrollFrame.size.width, 0, _scrollFrame.size.width, _scrollFrame.size.height);
        [_scrollView scrollRectToVisible:frame animated:NO];
    }else{
        CGRect frame = CGRectMake(0, pageIndex*_scrollFrame.size.height, _scrollFrame.size.width, _scrollFrame.size.height);
        [_scrollView scrollRectToVisible:frame animated:NO];
    }
    
    //移除没有加载的页面
    [self removeOthersItems:pageIndex];
    
    
    //加载pageIndex之前和之后的loadPageCount个页面
    for (int i=0; i<loadPageCount*2+1; i++) {
        [self loadScrollViewWithPage:pageIndex + (i - loadPageCount)];
    }
}

#pragma mark - UIGridViewItem delegate
//从item点击回调上来的
-(void) gridViewItemTapped:(GridViewItem *)gridViewItem{
    if (self.delegate) {
		[self.delegate gridView:self didSelectItemAtIndex:gridViewItem.tag-TagOfUIGridViewItem];
	}else{
        MyNSLog(@"GridViewItem's delegate is nil!!!");
    }
}

#pragma mark - Private Method
- (void)loadScrollViewWithPage:(int)pageIndex{
    if (pageIndex < 0)
        return;
    if (pageIndex >= _pages)
        return;
    
    if (self.dataSource) {
        for (int i=0; i<_rows; i++) {
            for (int j=0; j<_cols; j++) {
                int objIndex = pageIndex*(_rows*_cols)+i*_cols+j;
                if (objIndex < _totalCount) {
                    if (![_scrollView viewWithTag:TagOfUIGridViewItem + objIndex]) {
                        CGFloat x;
                        CGFloat y;
                        if (_direction) {//横向
                            x=_itemStartPoint.x+j*(_itemSize.width+_itemMargin.width) + pageIndex*_scrollView.frame.size.width;
                            y=_itemStartPoint.y+i*(_itemSize.height+_itemMargin.height);
                        }else{//纵向
                            x=_itemStartPoint.x+j*(_itemSize.width+_itemMargin.width);
                            y=_itemStartPoint.y+i*(_itemSize.height+_itemMargin.height) + + pageIndex*_scrollView.frame.size.height;
                        }
                        CGRect itemFrame = CGRectMake(x, y, _itemSize.width, _itemSize.height);
                        GridViewItem *item = [self.dataSource gridView:self itemAtIndex:objIndex];
                        item.delegate = self;
                        item.frame = itemFrame;
                        item.tag = TagOfUIGridViewItem + objIndex;
                        [_scrollView addSubview:item];
                        [item release];
                    }     
                }
            }
        }
    }else{
        MyNSLog(@"UIGridViewDataSource is nil!!!");
    }
}

#pragma mark - scrollView delegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
//    MyNSLog(@"scrollViewWillBeginDragging");
//    scrollView.scrollEnabled = NO;//如果在这里锁住ScrollView的话，scrollViewDidScroll将不会被调用！
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
//    MyNSLog(@"scrollViewDidEndDragging bool=%d",decelerate);
    [AppSession playMusic:VoiceFile(@"trash.caf")];
    scrollView.scrollEnabled = NO;//这里OK
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
//    MyNSLog(@"scrollViewWillBeginDecelerating");
//    scrollView.scrollEnabled = NO;//这里OK
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //只要在滚动就会回调该方法!
//    MyNSLog(@"scrollViewDidScroll");
//    scrollView.scrollEnabled = NO;//这里ERROR!!!
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//    MyNSLog(@"scrollViewDidEndDecelerating");
    
    //计算最终停止的页面
	int pageIndex = 0;
    // Switch the indicator when more than 50% of the previous/next page is visible
    if (_direction) {
        CGFloat pageWidth = _scrollView.frame.size.width;
        pageIndex = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth)  + 1;
    }else{
        CGFloat pageHeight = _scrollView.frame.size.height;
        pageIndex = floor((_scrollView.contentOffset.y - pageHeight / 2) / pageHeight) + 1;
    }
    if (pageIndex>=_pages || pageIndex<0) {
        MyNSLog(@"pageIndex is out of range:[0,%d]", _pages-1);
        return;
    }
    _pageControl.currentPage = pageIndex;
    _currentPageIndex = pageIndex;
    
    //移除没有加载的页面
    [self removeOthersItems:pageIndex];
    
    //加载pageIndex之前和之后的loadPageCount个页面
    for (int i=0; i<loadPageCount*2+1; i++) {
        [self loadScrollViewWithPage:pageIndex + (i - loadPageCount)];
    }
    
    
    
    //解锁scrollView
    scrollView.scrollEnabled = YES;
}

-(void)dealloc{
    [_gridViewItems release];
    _gridViewItems = nil;
    [_scrollView release];
    _scrollView = nil;
    [_pageControl release];
    _pageControl = nil;
    [_resuedGridItems release];
    _resuedGridItems = nil;
    
    [super dealloc];
}
@end
